import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.model_selection import train_test_split
import json
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import confusion_matrix
# 读取Excel文件，假设Excel文件中包含多个Sheet
def to_binary(number):
    return [int(digit) for digit in bin(number)[2:]]

xls = pd.ExcelFile('C:/Users/zlsjBIDF/Downloads/例子.xlsx')
df = pd.read_excel(xls)
df = df.dropna(subset=['delivery_setting'])
# 列名列表
column_names = ['landing_type', 'ad_type', 'is_comment_disable', 'ad_download_status', 'stat_cost', 'show_cnt', 'click_cnt', 'convert_cnt']
data_names = ['landing_type', 'ad_type', 'is_comment_disable', 'ad_download_status']
# 使用列表来选择DataFrame中的列
data = df[column_names]
df_encoded = pd.get_dummies(data, columns=['landing_type', 'ad_type', 'is_comment_disable', 'ad_download_status'])
df_encoded= df_encoded.fillna(0)
data = df_encoded.values
jisuan = np.empty((49842, 2))
for i in range(49842):
    if data[i][1] == 0:
        jisuan[i][0] = 0
    else:
        jisuan[i][0] = data[i][2] / data[i][1]
    if data[i][2]==0:
        jisuan[i][1] = 0
    else:
        jisuan[i][1]=data[i][3]/data[i][2]
label = np.empty(49842)
jishu = 0
for x in jisuan:
    if x[0]>0.1 or x[1]>0.03:
        label[jishu]=1
    else:
        label[jishu]=0
    jishu = jishu + 1
data = df[data_names]
data = pd.get_dummies(data, columns=['landing_type', 'ad_type', 'is_comment_disable', 'ad_download_status'])
data = data.values
data_deliveries = [json.loads(json_str) for json_str in df['delivery_setting'].values]
# 步骤1：确定所有唯一的键
keys = set(k for d in data_deliveries for k in d.keys())
keys_to_remove = ['end_time', 'start_time','schedule_time']
filtered_keys = ['bid_speed', 'bid_type', 'budget_mode', 'deep_bid_type', 'schedule_type', 'filter_night_switch', 'project_custom', 'budget_optimize_switch']
values_list = []
for i, delivery in enumerate(data_deliveries):
    row_values = []
    for k in filtered_keys:
        if k in delivery:
            row_values.append(delivery[k])
        else:
            # 键不存在时的处理方式，例如使用 None 或者默认值
            row_values.append(None)
    values_list.append(row_values)
print(filtered_keys)
y = np.array(values_list)

y = pd.DataFrame(y, columns=['bid_speed', 'bid_type', 'budget_mode', 'deep_bid_type', 'schedule_type', 'filter_night_switch', 'project_custom', 'budget_optimize_switch'])
y = pd.get_dummies(y, columns=['bid_speed', 'bid_type', 'budget_mode', 'deep_bid_type', 'schedule_type', 'filter_night_switch', 'project_custom', 'budget_optimize_switch'])

y = y.values
data = np.hstack((data, y))
for x in range(10):
    X_train, X_test, y_train, y_test = train_test_split(data, label, test_size=0.2, random_state=x)
    pca = PCA(n_components=0.90)
    X_train = pca.fit_transform(X_train)
    X_test = pca.fit_transform(X_test)
# 训练模型
    rf = LogisticRegression(C=1.0, random_state=42)

    # 训练模型
    rf.fit(X_train, y_train)
    # 训练模型
    # 预测
    y_pred = rf.predict(X_test)
    precision = precision_score(y_test, y_pred)

    accuracy = accuracy_score(y_test, y_pred)
    recall = recall_score(y_test, y_pred)
    print(f"Accuracy: {accuracy:.2f}")
    print(f"Precision for class '1': {precision:.2f}")
    print(f"recall: {recall:.2f}")
    cm = confusion_matrix(y_test, y_pred)
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')  # annot=True表示在每个单元格中显示数值
    plt.xlabel('Predicted labels')
    plt.ylabel('True labels')
    plt.title('Confusion Matrix')
    plt.show()